﻿using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Mini.Common;
using Mini.Model;
using Mini.Model.BaseModels;
using Mini.Resource;

namespace Mini.DownloadTool
{
    public partial class MainForm : BaseForm
    {
        #region BindSource
        private BindingList<PageModel> _pageListBindingSource;
        private BindingList<AnalysisLinkModel> _listLinkBindingSource;
        #endregion

        public MainForm()
        {
            InitializeComponent();

            // Register Bind Source
            GridRegister();
            // Event 
            EventRegister();
        }

        #region Textbox Event
        private void textBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                btnAddPage.PerformClick();
            }
        }
        #endregion

        #region button event

        private async void btnStart_Click(object sender, EventArgs e)
        {
     
            if (_isStart)
                return;

            // step 1 : validation input
            var isSuscess = ValidationHelper.ValidationTextBoxAfterStart(this);
            if (!isSuscess)
            {
                MessageBox.Show(MessageResource.FolderRequired, MessageResource.WarningTitle);
                return;
            }
            await ProgramHelper.SetStatus(200, "Start!!!!!!!!!", rtxtStatus);
            // step 2 : set status button start

            SetStatusButtonStart(true);
            await ProgramHelper.SetStatus(200, "Create Folder!!!!!!!!!", rtxtStatus);
            var siteName = Regex.Replace(txtSiteName.Text, RegexResource.SpecialChar, "");
            // step 3 : create  project folder
            var projectDirectory = Path.Combine(txtSaveTo.Text, siteName);
            DirectoryHelper.CreateProjectFolder(projectDirectory);
            const string messageProcess = "Page Name: {0} - {1}";
            // step 4 : get page list in dgvListPage
            foreach (var itemPage in _pageListBindingSource)
            {
                await ProgramHelper.SetStatus(200, string.Format(messageProcess, itemPage.PageName, "Get Link"), rtxtStatus);
                itemPage.PageStatus = PageStatus.Processing;
                ListPageRefresh();
                await ProgramHelper.SetStatus(200, string.Format(messageProcess, itemPage.PageName, "Analysis Page(Get all link in page)"), rtxtStatus);
                var allLinkinPage = await FilterHelper.AnalysisPage(itemPage, projectDirectory);

                var pageName = itemPage.PageName;
                allLinkinPage.AnalysisLinkModels.ForEach(c => c.ProjectName = pageName);

                AddDataToListBindingSource(allLinkinPage.AnalysisLinkModels.ToList());

                var sitePage = Path.Combine(projectDirectory, itemPage.PageName);
                var pageModel = allLinkinPage.PageModel;
                var htmlString = new StringBuilder(pageModel.PageContent);
                await ProgramHelper.SetStatus(200, string.Format(messageProcess, itemPage.PageName, "Begin Download"), rtxtStatus);
                foreach (var linkInPage in _listLinkBindingSource)
                {
                    var messageDownload = string.Format(messageProcess, itemPage.PageName, "Begin Download Link");
                    await ProgramHelper.SetStatus(200, string.Format("{0} {1} {2}", messageDownload, Environment.NewLine, linkInPage.BaseLink),rtxtStatus);
                    var localLink = await DownloadHelper.DownloadContentWebSite(linkInPage, sitePage);
                    linkInPage.Downloaded = true;

                    linkInPage.LocalLink = localLink.LocalLink;
                    linkInPage.ProjectLink = localLink.ProjectLink;
                    ListLinkRefresh();
                    htmlString.Replace(linkInPage.BaseLink, localLink.ProjectLink);
                }
                await ProgramHelper.SetStatus(200, string.Format(messageProcess, itemPage.PageName, "Save file!!!!"), rtxtStatus);
                await FileHepler.UpdateStringToFile(pageModel.PageDirectory, htmlString.ToString());

                var folderItemPage = Path.Combine(sitePage, ConvertHelper.ConvertFolderTypeToString(FolderType.Css));

                await ProgramHelper.SetStatus(200, string.Format(messageProcess, itemPage.PageName, "Get all && filter file css!!!!"), rtxtStatus);

                var listLinkImageInFileCss = await FilterHelper.FilterLinkInCssFiles(itemPage.PageLink, folderItemPage, _listLinkBindingSource, rtxtStatus);

                await ProgramHelper.SetStatus(200, string.Format(messageProcess, itemPage.PageName, "Begin download file in file css!!!!"), rtxtStatus);

                var regexReplace = new Regex(RegexResource.RegexContent);
                foreach (var imageInCss in listLinkImageInFileCss)
                {
                    await ProgramHelper.SetStatus(200, string.Format(messageProcess, itemPage.PageName, Environment.NewLine), rtxtStatus);
                    var dataCss = new StringBuilder(imageInCss.CssData);
                    foreach (var imageInCssLink in imageInCss.ImageInCssLinks)
                    {
                        var messageDownloadCss = string.Format(messageProcess, itemPage.PageName, "Begin Download Link");
                        await ProgramHelper.SetStatus(200, string.Format("{0} {1} {2}", messageDownloadCss, Environment.NewLine, imageInCssLink.BaseLink), rtxtStatus);

                        var fileName = FileHepler.GetFileNameFromUrl(imageInCssLink.BaseLink);
                        var folderFile = ConvertHelper.ConvertFolderTypeToString(FolderType.Images);
                        if (FileHepler.IsFont(fileName))
                        {
                            folderFile = ConvertHelper.ConvertFolderTypeToString(FolderType.Fonts);
                        }

                        fileName = regexReplace.Replace(fileName, "");
                        var projectImageInCssUrl = string.Format("{0}/{1}", folderFile, fileName);
                        if (UrlHelper.IsUrlExits(imageInCssLink.OnlineLink))
                        {
                            var fileDirectory = Path.Combine(sitePage, folderFile, fileName);
                            await DownloadHelper.DownloadFile(imageInCssLink.OnlineLink, fileDirectory);
                        }
                        else
                        {
                            projectImageInCssUrl = string.Empty;
                        }
                        dataCss = dataCss.Replace(imageInCssLink.BaseLink, projectImageInCssUrl);
                    }
                    await ProgramHelper.SetStatus(200, string.Format("Save File: {0} {1}", Environment.NewLine, imageInCss.CssLink), rtxtStatus);
                    await FileHepler.UpdateStringToFile(imageInCss.CssLink, dataCss.ToString());
                }
                itemPage.PageStatus = PageStatus.Success;
                ListPageRefresh();
                await ProgramHelper.SetStatus(200, string.Format(messageProcess, itemPage.PageName, "Download Complete!!!!!!"), rtxtStatus);
            }
            SetStatusButtonStart(false);
            MessageBox.Show(@"Download all complete!!!!!!");
        }

        private void btnAddPage_Click(object sender, EventArgs e)
        {
            var pageName = txtPageName.Text;
            var pageLink = txtPageLink.Text;
            var regexReplace = new Regex(RegexResource.SpecialChar);
            if (string.IsNullOrEmpty(pageName))
            {
                var link = txtPageLink.Text;
                if (!string.IsNullOrEmpty(link))
                {
                    var nameSplit = link.Split("/");
                    if (nameSplit.Any())
                    {
                        var name = nameSplit.LastOrDefault(c => !string.IsNullOrEmpty(c));
                        if (name != null)
                        {
                            var regex = regexReplace.Replace(name, "");
                            if (!string.IsNullOrEmpty(regex))
                            {
                                pageName = name;
                            }
                        }
                    }
                }
            }
            pageName = regexReplace.Replace(pageName, "");
            if (!string.IsNullOrWhiteSpace(pageLink) && !string.IsNullOrWhiteSpace(pageName) && UrlHelper.IsUrl(pageLink))
            {
                var pageModel = new PageModel
                                    {
                                        PageName = pageName,
                                        PageLink = pageLink,
                                        PageStatus = PageStatus.Pending
                                    };

                _pageListBindingSource.Add(pageModel);
                ListPageRefresh();
                txtPageName.Text = string.Empty;
                txtPageLink.Text = string.Empty;
            }
            else
            {
                MessageBox.Show(MessageResource.UrlRequired, MessageResource.WarningTitle);
            }
        }

        private void btnClearData_Click(object sender, EventArgs e)
        {
            _listLinkBindingSource.Clear();
            _pageListBindingSource.Clear();
            ListPageRefresh();
            ListLinkRefresh();
            txtSiteName.Text = string.Empty;
            rtxtStatus.Text = string.Empty;
            ProcessBar.Value = 0;
        }

        #endregion
    }
}
